package com.kwdata.quartz.task;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kwdata.quartz.domain.Patient;
import com.kwdata.quartz.dto.PatientDto;
import com.kwdata.quartz.dto.PatientQueryDto;
import com.kwdata.quartz.exception.CustomException;
import com.kwdata.quartz.param.ResponseParam;
import com.kwdata.quartz.service.IPatientService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Component("patientInfoTask")
public class PatientInfoTask {

    @Resource
    IPatientService patientService;

    @Value("${shujuzhontai.url}")
    private String url;

    @Value("${shujuzhontai.authorization}")
    private String token;

    @Value("${shujuzhontai.pagesize}")
    private String pagesize;

    @Value("${shujuzhontai.sleep}")
    private String sleep;

    private String param = "{" +
            "main_cable_no\": \"2962193520\",\n" +
            "start_date\": \"@startDate\",\n" +
            "end_date\": \"@endDate\",\n" +
            "offset\": \"@page\",\n" +
            "rowNum\": \"@Size\"\n" +
            "}";


    /**
     * 每小时执行一次 0 0 * * * ?
     */
    @Scheduled(cron = "0 0 * * * ?")
    public void getInfoScheduled() {
        log.debug("定时抽取患者信息-开始----------当前时间{}--------------------", DateUtil.format(new Date(), "YYYY-MM-dd HH:mm:ss"));
        this.getInfo(null);
        log.debug("定时抽取患者信息-结束-----------------------------------------------");
    }

    public void getInfo(PatientQueryDto queryDto) {
        log.info("url={}", url);
        log.info("token={}", token);
        String startDate;
        String endDate;
        if (queryDto == null) {
            String format = DateUtil.format(new Date(), "YYYY-MM-dd");
            startDate = format + " 00:00:00";
            endDate = format + " 23:59:59";
        } else {
            startDate = queryDto.getStartDate() + " 00:00:00";
            endDate = queryDto.getEndDate() + " 23:59:59";
        }
        //String body = param.replace("@startDate", startDate).replace("@endDate", endDate);
        Map<String, String> headerMap = new LinkedHashMap<>();
        headerMap.put("Content-Type", "application/json");
        headerMap.put("Authorization", token);
        //调用接口
        String responseParam = "查询无结果";
        //分页大小
        int pageSize = Integer.parseInt(pagesize);
        for (int i = 0; i < 100000 * 10000; i = i + pageSize) {
            Map<String, String> map = new LinkedHashMap<>();
            map.put("start_date", startDate);
            map.put("end_date", endDate);
            map.put("offset", String.valueOf(i));
            map.put("rowNum", String.valueOf(i + pageSize));
            String body = JSONUtil.toJsonStr(map);
            log.info("body:{}", body);
            System.out.println("body：" + body);
            try {
                responseParam = HttpRequest.post(url)
                        .headerMap(headerMap, true)
                        .timeout(1000 * 60 * 5)
                        .body(body)
                        .execute()
                        .body();
                //测试用 TODO
                //responseParam = ResponseParam.res;
            } catch (Exception e) {
                log.error("调用失败:{}", e.getMessage());
                log.error("-----------------------------------------------------");
                log.error("响应内容：{}", responseParam);
                throw new CustomException("调用失败:" + e.getMessage());
            }
            System.out.println("响应部分内容：" + responseParam);
            //解析参数
            JSONObject jsonObject = JSONUtil.parseObj(responseParam);
            if (ObjectUtil.isEmpty(jsonObject.get("code"))) {
                System.out.println("响应格式不正确：" + responseParam);
                log.error("响应格式不正确，{}", responseParam);
                throw new CustomException("响应格式不正确：" + responseParam);
            }
            if (!jsonObject.get("code").toString().equals("200")) {
                log.error("调用失败，{}", responseParam);
                throw new CustomException("code！=200，响应内容：" + responseParam);
            }
            Object data = jsonObject.get("data");
            List<PatientDto> patientDtoList = JSONUtil.toList(data.toString(), PatientDto.class);
            int size = patientDtoList.size();
            log.debug("得到{}条患者信息", size);
            System.out.println("得到" + size + "条患者信息");
            if (patientDtoList.size() == 0) return;
            //查询已有的数据
            LambdaQueryWrapper<Patient> lqw = new LambdaQueryWrapper<>();
            lqw.select(Patient::getJzlsh);
            lqw.between(Patient::getRyzlsj, startDate, endDate);
            List<Patient> oldList = patientService.list(lqw);
            List<String> idOldList = oldList.stream().map(Patient::getJzlsh).distinct().collect(Collectors.toList());
            List<Patient> newList = new ArrayList<>();
            //增量更新
            patientDtoList = patientDtoList.stream().filter(f -> !idOldList.contains(f.getEncnt_no())).collect(Collectors.toList());
            //封装参数
            for (PatientDto pd : patientDtoList) {
                Patient entity = new Patient();
                this.setData(pd, entity);
                newList.add(entity);
            }
            //插入数据库
            if (newList.size() > 0) {
                patientService.saveBatch(newList);
            }
            //得到的数据小于分页条数，说明已到最后一页，退出循环
            if (size < pageSize) {
                System.out.println("最后一页，循环结束，end");
                return;
            } else {
                //循环调用休眠
                try {
                    System.out.println("调用结束，开始休眠，休眠" + sleep + "秒");
                    Thread.sleep(1000L * Integer.parseInt(sleep));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("休眠结束，进入下次调用");
            }
        }
    }

    private void setData(PatientDto pd, Patient entity) {
        //诊疗类型
        if (ObjectUtil.isNotEmpty(pd.getOutpat_no())) {
            entity.setZllx("门诊");
            //病案号
            entity.setBah(pd.getOutpat_no());
        }
        if (ObjectUtil.isNotEmpty(pd.getInpatient_no())) {
            entity.setZllx("住院");
            //病案号
            entity.setBah(pd.getInpatient_no());
        }
        //性别
        String sex = "未填";
        if (ObjectUtil.isNotEmpty(pd.getSex_code())) {
            switch (pd.getSex_code()) {
                case "0":
                    sex = "未知";
                    break;
                case "1":
                    sex = "男";
                    break;
                case "2":
                    sex = "女";
                    break;
            }
        }
        entity.setXb(sex);
        //就诊流水号
        entity.setJzlsh(pd.getEncnt_no());
        //住院次数
        entity.setZycs(pd.getVisitno() == null ? "" : pd.getVisitno());
        //姓名
        entity.setXm(pd.getPatientname() == null ? "" : pd.getPatientname());
        //出生日期
        entity.setCsrq(pd.getBirthday() == null ? "" : pd.getBirthday());
        //年龄
        entity.setNl(pd.getAge());
        //单位
        entity.setNldw(pd.getAgeunit() == null ? "" : pd.getAgeunit());
        //床号
        entity.setCh(pd.getBedno() == null ? "" : pd.getBedno());
        //医疗付款方式
        entity.setYlfkfs(pd.getYlfkfs() == null ? "" : pd.getYlfkfs());
        //入院诊疗时间
        entity.setRyzlsj(pd.getRysj() == null ? "" : pd.getRysj());
        //患者所在科室
        entity.setHzszks(pd.getRyks() == null ? "" : pd.getRyks());
        //门诊诊断
        entity.setMzzd(pd.getMzzd() == null ? "" : pd.getMzzd());
        //门诊诊断编码
        entity.setMzzdbm(pd.getMzzdbm() == null ? "" : pd.getMzzdbm());
        //主要诊断
        entity.setZyzd(pd.getZyzd() == null ? "" : pd.getZyzd());
        //主要诊断编码
        entity.setZyzdbm(pd.getZyzdbm() == null ? "" : pd.getZyzdbm());
        //护理级别
        entity.setHljb(pd.getNurselevel() == null ? "" : pd.getNurselevel());
        //身高
        entity.setSg(this.change(pd.getHeight()));
        //体重
        entity.setTz(this.change(pd.getWeight()));
        //民族
        entity.setMz(pd.getNation() == null ? "" : pd.getNation());
        //电话
        entity.setDh(pd.getPhone() == null ? "" : pd.getPhone());
        //职业
        entity.setZy(pd.getProfession() == null ? "" : pd.getProfession());
    }

    public String change(String value) {
        if (ObjectUtil.isEmpty(value)) {
            return "";
        } else {
            return value;
        }
    }


}
